﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.ObjectModel;

namespace Calhoon.MarkupParser
{
	public class DocumentHierarchyCreator
	{
		private Collection<PrimitiveTag> mInput;
		public Collection<PrimitiveTag> Input {
			get {
				return mInput;
			}
		}

		private TagConverter mTagConverter;
		public TagConverter TagConverter {
			get {
				return mTagConverter;
			}
			set {
				mTagConverter = value;
			}
		}

		public DocumentHierarchyCreator() {
			mInput = new Collection<PrimitiveTag>();
		}

		public HierarchyNode BuildHierarchy(PrimitiveTag[] input, TagConverter converter) {
			mInput = new Collection<PrimitiveTag>(input);
			mTagConverter = converter;

			return BuildHierarchy();
		}

		public virtual HierarchyNode BuildHierarchy() {
			RootNode root = new RootNode();

			Stack<HierarchyNode> tagStack = new Stack<HierarchyNode>();
			tagStack.Push(root);

			foreach (PrimitiveTag tag in mInput) {
				if (!tag.IsClosing) {
					HierarchyNode node = mTagConverter.GetHierarchyNode(tag);
					if (node != null) {
						tagStack.Peek().Children.Add(node);

						if (!tag.IsSelfClosing && !mTagConverter.IsSelfClosing(tag)) {
							tagStack.Push(node);
						}
					}
				}
				else {
					Stack<HierarchyNode> tempStack = new Stack<HierarchyNode>();
					while (tagStack.Count > 0 && tagStack.Peek().TagName != tag.TagName) {
						tempStack.Push(tagStack.Pop());
					}

					if (tagStack.Count > 0 && tagStack.Peek().TagName == tag.TagName) {
						tagStack.Pop();
					}
					else {
						while (tempStack.Count > 0) {
							tagStack.Push(tempStack.Pop());
						}
					}
				}
			}

			return root;
		}
	}
}